package jp.ac.waseda.info.ueda.unyo.panel;

import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.JSeparator;
import javax.swing.SpinnerNumberModel;

import jp.ac.waseda.info.ueda.unyo.generator.GraphController;
import jp.ac.waseda.info.ueda.unyo.manager.NodeAdjustmentMover;
import jp.ac.waseda.info.ueda.unyo.manager.NodeCalculator;
import jp.ac.waseda.info.ueda.unyo.manager.NodeMover;
import jp.ac.waseda.info.ueda.unyo.mediator.LMNtalRuntime;
import jp.ac.waseda.info.ueda.unyo.node.ActiveNode_Membrane;
import jp.ac.waseda.info.ueda.unyo.util.Logger;

public class EditNodeFrame extends JDialog{
	final static
	private String TITLE = "Edit Node";

	final static
	private int WIDTH = 300;

	final static
	private int HEIGHT = 120;

	static
	private ActiveNode_Membrane targetMem_;

	static
	private Object targetAtom_;

	private JTextField atomNameField_;
	private JSpinner atomNumSpinner_;
	private JTextField membraneNameField_;
	private JSpinner membraneNumSpinner_;

	public EditNodeFrame(){

	}

	public EditNodeFrame(Frame owner){
		super(owner, false);

		JLabel createNodeLabel_ = null;
		JLabel nameLabel_ = null;
		JButton addBt_ = null;
		JSeparator separator_ = null;
		SpinnerNumberModel model = null;
		JSpinner.NumberEditor editor = null;
		JFormattedTextField ftext = null;

		setTitle(TITLE);

		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setSize(WIDTH, HEIGHT);
		setLayout(new GridBagLayout());

		GridBagConstraints gbc = new GridBagConstraints();

		////////////////////////////////////////////
		// Atom
		gbc.fill = GridBagConstraints.CENTER;
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.gridwidth = 4;
		createNodeLabel_ = new JLabel("Create new Atom.");
		add(createNodeLabel_, gbc);

		gbc.fill = GridBagConstraints.BOTH;
		gbc.gridx = 0;
		gbc.gridy += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 0.0;
		nameLabel_ = new JLabel("Name : ");
		add(nameLabel_, gbc);

		gbc.gridx += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 1.0;
		atomNameField_ = new JTextField();
		atomNameField_.addActionListener(new AddAtomNodeListener());
		add(atomNameField_, gbc);

	    model = new SpinnerNumberModel(1, 1, null, 1);
		atomNumSpinner_ = new JSpinner(model);
		editor = new JSpinner.NumberEditor(atomNumSpinner_, "0000");
		editor.setVerifyInputWhenFocusTarget(true);
		atomNumSpinner_.setFocusable(false);
	    ftext = editor.getTextField();
	    ftext.setEditable(true);
	    atomNumSpinner_.setEditor(editor);
	    gbc.gridwidth = 1;
		gbc.gridx += 1;
		gbc.weightx = 0.0;
		add(atomNumSpinner_, gbc);

		gbc.gridx += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 0.0;
		addBt_ = new JButton("Add Atom");
		addBt_.addActionListener(new AddAtomNodeListener());
		add(addBt_, gbc);

		gbc.gridx = 0;
		gbc.gridy += 1;
		gbc.gridwidth = 4;
		separator_ = new JSeparator(JSeparator.HORIZONTAL);
		add(separator_, gbc);

		////////////////////////////////////////////
		// Membrane
		gbc.fill = GridBagConstraints.CENTER;
		gbc.gridx = 0;
		gbc.gridy += 1;
		gbc.gridwidth = 4;
		createNodeLabel_ = new JLabel("Create new Membrane.");
		add(createNodeLabel_, gbc);

		gbc.fill = GridBagConstraints.BOTH;
		gbc.gridx = 0;
		gbc.gridy += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 0.0;
		nameLabel_ = new JLabel("Name : ");
		add(nameLabel_, gbc);

		gbc.gridx += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 1.0;
		membraneNameField_ = new JTextField();
		membraneNameField_.addActionListener(new AddMembraneNodeListener());
		add(membraneNameField_, gbc);

	    model = new SpinnerNumberModel(1, 1, null, 1);
		membraneNumSpinner_ = new JSpinner(model);
		editor = new JSpinner.NumberEditor(membraneNumSpinner_, "0000");
		editor.setVerifyInputWhenFocusTarget(true);
		membraneNumSpinner_.setFocusable(false);
	    ftext = editor.getTextField();
	    ftext.setEditable(true);
	    membraneNumSpinner_.setEditor(editor);
	    gbc.gridwidth = 1;
		gbc.gridx += 1;
		gbc.weightx = 0.0;
		add(membraneNumSpinner_, gbc);

		gbc.gridx += 1;
		gbc.gridwidth = 1;
		gbc.weightx = 0.0;
		addBt_ = new JButton("Add Membrane");
		addBt_.addActionListener(new AddMembraneNodeListener());
		add(addBt_, gbc);

	}

	static
	public void setMem(ActiveNode_Membrane mem){
		targetMem_ = mem;
	}
	static
	public void setAtom(Object atom){
		targetAtom_ = atom;
	}

	private class AddAtomNodeListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if(targetMem_ == null){
				Logger.errPrintln(Logger.MSG_NO_TARGET_MEM);
				return;
			}
			String name = atomNameField_.getText();
			GraphController gc = LMNtalRuntime.getGraphController();
			if(name.equals("")){
				return;
			}
			NodeMover.setWait(true);
			NodeCalculator.setWait(true);
			NodeAdjustmentMover.setWait(true);
			while(!NodeMover.isWaiting() ||
					!NodeCalculator.isWaiting() || 
					!NodeAdjustmentMover.isWaiting())
			{
				try {
					Thread.sleep(50);
				} catch (InterruptedException e2) {
					e2.printStackTrace();
				}
			}
			for (int i = 0; i < (Integer)atomNumSpinner_.getValue(); i++) {
				gc.addAtom(targetMem_.getNode(), name);
			}
			targetMem_.groupConnectedGraph(MainFrame.getCurrentGraphPanel());
			NodeMover.setWait(false);
			NodeCalculator.setWait(false);
			NodeAdjustmentMover.setWait(false);
		}

	}

	private class AddMembraneNodeListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if(targetMem_ == null){
				Logger.errPrintln(Logger.MSG_NO_TARGET_MEM);
				return;
			}
			String name = membraneNameField_.getText();
			GraphController gc = LMNtalRuntime.getGraphController();
			NodeMover.setWait(true);
			NodeCalculator.setWait(true);
			NodeAdjustmentMover.setWait(true);
			while(!NodeMover.isWaiting() ||
					!NodeCalculator.isWaiting() || 
					!NodeAdjustmentMover.isWaiting())
			{
				try {
					Thread.sleep(50);
				} catch (InterruptedException e2) {
					e2.printStackTrace();
				}
			}
			for (int i = 0; i < (Integer)membraneNumSpinner_.getValue(); i++) {
				gc.addMembrane(targetMem_.getNode(), name);
			}
			targetMem_.groupConnectedGraph(MainFrame.getCurrentGraphPanel());
			NodeMover.setWait(false);
			NodeCalculator.setWait(false);
			NodeAdjustmentMover.setWait(false);
		}
	}

}
